﻿using System;
using System.Collections.Generic;

namespace Framework
{
    /// <summary>
    /// 引用池
    /// </summary>
    public class ReferencePool
    {
        private static Dictionary<string, List<IReference>> m_References = new Dictionary<string, List<IReference>>();

        /// <summary>
        /// 获取指定类型的引用
        /// </summary>
        /// <typeparam name="T">引用类型</typeparam>
        /// <returns>获得应用</returns>
        public static T GetReference<T>() where T : class, IReference, new()
        {
            string typeName = typeof(T).ToString();
            List<IReference> list = null;
            if (m_References.TryGetValue(typeName, out list))
            {
                if (list.Count > 0)
                {
                    IReference reference = list[list.Count - 1];
                    list.RemoveAt(list.Count - 1);
                    reference.Init();
                    return reference as T;
                }
            }
            T t = new T();
            t.Init();
            return t;
        }
        /// <summary>
        /// 回收指定类型的引用
        /// </summary>
        /// <typeparam name="T">要回收的引用的类型</typeparam>
        /// <param name="reference">要回收的引用</param>
        public static void Collect<T>(IReference reference) where T : class, IReference, new()
        {
            string typeName = typeof(T).ToString();
            if (!m_References.ContainsKey(typeName))
            {
                m_References.Add(typeName, new List<IReference>());
            }
            reference.Collect();
            if (!m_References[typeName].Contains(reference))
                m_References[typeName].Add(reference);
        }
        public static void Collect(Type type, IReference reference)
        {
            string typeName = type.ToString();
            if (!m_References.ContainsKey(typeName))
            {
                m_References.Add(typeName, new List<IReference>());
            }
            reference.Collect();
            if (!m_References[typeName].Contains(reference))
                m_References[typeName].Add(reference);
        }
        /// <summary>
        /// 清空引用池
        /// </summary>
        public static void Clear()
        {
            foreach (KeyValuePair<string, List<IReference>> item in m_References)
            {
                for (int i = 0; i < item.Value.Count; i++)
                {
                    item.Value[i].Destroy();
                }
            }
            m_References.Clear();
        }
        /// <summary>
        /// 销毁
        /// </summary>
        public static void Destroy()
        {
            Clear();
            m_References = null;
        }
        /// <summary>
        /// 获得引用池中所有引用类型
        /// </summary>
        /// <returns>引用类型集合</returns>
        public static void GetAllReferenceType(ref List<Type> list)
        {
            if (list == null) return;
            foreach (var item in m_References)
            {
                Type type = Type.GetType(item.Key);
                list.Add(type);
            }
        }
        /// <summary>
        /// 获得指定类型引用的可用数量
        /// </summary>
        /// <param name="type">引用类型</param>
        /// <returns>可用引用数量</returns>
        public static int GetFreeReferenceCount(Type type)
        {
            string typeName = type.ToString();
            if (m_References.ContainsKey(typeName))
                return m_References[typeName].Count;
            return 0;
        }
    }
}
